/*
 * test_arena.cpp
 *
 *  Created on: Nov 23, 2013
 *      Author: killerg
 */





#include "share/util.h"
#include <stdint.h>

#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include <list>
#include <vector>
#include <map>

using namespace std;

#define RANK_SIZE 2
#define OPPO_SIZE 1

struct rank_list_t {
    bool init(const Json::Value &json) {
        if (!json.isArray())
            return false;

        for (auto itr = json.begin(); itr != json.end(); ++itr)
            insert((*itr).asInt64(), -1);

        return true;
    }
    void save(Json::Value &json) {
        for (auto itr = id_lst.begin(); itr != id_lst.end(); ++itr)
            json.append(Json::Int64(*itr));
    }
    void destroy() {
        itr_map.clear();
        id_lst.clear();
    }
    void update();

    bool insert(int64_t playerid, int64_t before_playerid) {
        if (itr_map.count(playerid) == 0) {
            auto itr = id_lst.insert(id_lst.end(), playerid);
            itr_map[playerid] = itr;
        }

        if (itr_map.count(before_playerid) == 0)
            return false;

        auto itr = itr_map[playerid];
        id_lst.erase(itr);
        itr = itr_map[before_playerid];
        itr = id_lst.insert(itr, playerid);
        itr_map[playerid] = itr;

        while (id_lst.size() > RANK_SIZE) {
            int64_t back = id_lst.back();
            id_lst.pop_back();
            itr_map.erase(back);
        }

        return true;
    }
    void query(int64_t playerid, int interval, list<int64_t> &lst) {
        interval = std::max(1, interval);

        auto itr = itr_map[playerid];
        auto begin = id_lst.begin();
        int step = 0;
        while (itr != begin) {
            if (*itr != playerid) {
                if (step == interval) {
                    step = 0;
                    lst.push_front(*itr);
                    if (lst.size() >= OPPO_SIZE)
                        break;
                }
                ++step;
            }
            --itr;
        }

        if (lst.size() < OPPO_SIZE && itr == begin && *itr != playerid) {
            lst.push_front(*itr);
        }
    }

    map<int64_t, list<int64_t>::iterator> itr_map;
    list<int64_t> id_lst;
};

bool test_arena() {
    rank_list_t arena;
    for (int i=0; i<10; ++i) {
        arena.insert(i, i-1);
    }

    Json::Value json;
    arena.save(json);
    arena.destroy();
    arena.init(json);

    list<int64_t> lst;
    arena.query(9, 10, lst);
    assert(lst.empty());

    list<int64_t> lst2;
    arena.query(0, 10, lst2);
    assert(lst2.size() == 9);

    list<int64_t> lst3;
    arena.query(8, 1, lst3);
    assert(lst3.size() == 1);

    printf("eend\n");
    return true;
}
